/*
 * 版权所有(C)，方太互联网应用技术部，lizhixing，所有权利保留。
 * <p>
 * 项目名：	algorithm-demo
 * 文件名：	Question1456
 * 模块说明：
 * 修改历史：
 * 2025/4/17 - lizhixing - 创建。
 */
package com.lovely602.algorithm.wansuanfa;

/**
 * 给你字符串 s 和整数 k 。请返回字符串 s 中长度为 k 的单个子字符串中可能包含的最大元音字母数。英文中的 元音字母 为（a, e, i, o, u）。
 * <p>
 * 示例1： 输入：s = "abciiidef", k = 3
 * <p>
 * 输出：3
 * <p>
 * 解释：子字符串 "iii" 包含 3 个元音字母。
 * <p>
 * 示例2： 输入：s = "aeiou", k = 2
 * <p>
 * 输出：2
 * <p>
 * 解释：任意长度为 2 的子字符串都包含 2 个元音字母。
 * <p>
 * <p>
 * 1 <= s.length <= 10^5
 * <p>
 * s 由小写英文字母组成
 * <p>
 * 1 <= k <= s.length
 * <p>
 * <p>
 * 问题分析
 * <p>
 * <p>
 * <p>
 * 这题让计算长度为 k 的子串中元音字母的最大个数，实际上这就是一道滑动窗口问题，并且窗口大小还是固定的，长度是 k 。
 * <p>
 * 刚开始的时候只滑动窗口的右边界，然后累加窗口中元音字母的个数 cnt ，当窗口长度达到 k 的时候，记录下窗口中元音字母的个数。
 * <p>
 * 接着窗口的两边同时往右滑动，以确保窗口的长度始终为 k 。窗口的右边是添加字母，窗口的左边是移出字母，如果添加的是元音字母，则 cnt 要加 1 ，如果移除的是元音字母，则 cnt 要减 1
 * 。后续每次滑动的时候都要保存窗口中元音字母的最大个数。
 *
 * @author lizhixing
 */
public class Question1456 {

  public static void main(String[] args) {

    String word = "abciiidef";
    int k = 3;
    int vowelNum = new Question1456().maxVowels(word, k);
    System.out.println("元音字母的最大个数：" + vowelNum);

  }

  public int maxVowels(String s, int k) {
    int left = 0, right = 0, n = s.length();
    int cnt = 0;// 当前窗口中元音字母的个数
    int ans = 0;// 记录窗口内的最大元音字母个数
    while (right < n) {
      // 判断窗口右边是否是元音字母，如果是就加上
      cnt += isVowel(s.charAt(right++));
      // 窗口长度等于 k 的时候开始记录最大元音字母个数
      if (right - left == k) {
        ans = Math.max(ans, cnt);// 保存最大值
        // 因为是固定窗口，窗口左边的元素要出窗口
        cnt -= isVowel(s.charAt(left++));
      }
    }
    return ans;
  }

  // 是元音字母返回1，否则返回0
  private int isVowel(char ch) {
    return ch == 'a' || ch == 'e' || ch == 'i'
        || ch == 'o' || ch == 'u' ? 1 : 0;
  }

}
